// Fill out your copyright notice in the Description page of Project Settings.


#include "Core/PlayerController2D.h"
#include "EnhancedInputSubsystems.h"
#include "EnhancedInputComponent.h"
#include "Core/Player2D.h"
#include "StateMachine/StateMachine.h"
#include "StateMachine/PlayerState/DashState.h"
#include "StateMachine/PlayerState/FallState.h"
#include "StateMachine/PlayerState/IdleState.h"
#include "StateMachine/PlayerState/JumpState.h"
#include "StateMachine/PlayerState/MoveState.h"



APlayerController2D::APlayerController2D()
{
}

void APlayerController2D::BeginPlay()
{
	Super::BeginPlay();
	bShowMouseCursor = true;


	UEnhancedInputLocalPlayerSubsystem* InputSubsystem = GetLocalPlayer()->GetSubsystem<UEnhancedInputLocalPlayerSubsystem>();
	if (InputSubsystem)
		InputSubsystem->AddMappingContext(IMContext, 1);
}

void APlayerController2D::OnPossess(APawn* InPawn)
{
	Super::OnPossess(InPawn);
	PossessPlayer = Cast<APlayer2D>(InPawn);
	InitStateMachine();
}

void APlayerController2D::InitStateMachine()
{
	if (!StateMachine)
	{
		StateMachine = NewObject<UStateMachine>();
	}
	StateMachine->Init(this, PossessPlayer);
	
	UGroundState* GroundState = NewObject<UGroundState>();
	GroundState->Init(this, PossessPlayer, StateMachine);
	StateMachine->AddState(GroundState);

	UIdleState* IdleState = NewObject<UIdleState>();
	IdleState->Init(this, PossessPlayer, StateMachine);
	StateMachine->AddState(IdleState);

	UMoveState* MoveState = NewObject<UMoveState>();
	MoveState->Init(this, PossessPlayer, StateMachine);
	StateMachine->AddState(MoveState);

	UDashState* DashState = NewObject<UDashState>();
	DashState->Init(this, PossessPlayer, StateMachine);
	StateMachine->AddState(DashState);

	UJumpState* JumpState = NewObject<UJumpState>();
	JumpState->Init(this, PossessPlayer, StateMachine);
	StateMachine->AddState(JumpState);

	UFallState *FallState = NewObject<UFallState>();
	FallState->Init(this, PossessPlayer, StateMachine);
	StateMachine->AddState(FallState);
	
	
	StateMachine->SwitchState(UIdleState::StaticClass());
}

void APlayerController2D::SetupInputComponent()
{
	Super::SetupInputComponent();

	UEnhancedInputComponent* Input =  Cast<UEnhancedInputComponent>(InputComponent);
	if (Input)
	{
		Input->BindAction(IA_Move, ETriggerEvent::Triggered, this, &APlayerController2D::OnMove);
		Input->BindAction(IA_Move, ETriggerEvent::Completed, this, &APlayerController2D::OnMoveStop);
		Input->BindAction(IA_Dash, ETriggerEvent::Started, this, &APlayerController2D::OnDash);
		Input->BindAction(IA_Jump, ETriggerEvent::Started, this, &APlayerController2D::OnJump);
		Input->BindAction(IA_Jump,ETriggerEvent::Started, this, &APlayerController2D::OnAttack);
	}
	
}

void APlayerController2D::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
	if (StateMachine)
	{
		StateMachine->Tick(DeltaTime);
	}
}

void APlayerController2D::OnMoveStop(const FInputActionValue& Value)
{
	if (StateMachine)
	{
		StateMachine->InputSignal(EInputSignal::MoveEnd, Value);
	}
}

void APlayerController2D::OnMove(const FInputActionValue& Value)
{
	if (StateMachine)
	{
		StateMachine->InputSignal(EInputSignal::Moving, Value);
	}
}

void APlayerController2D::OnDash(const FInputActionValue& Value)
{
	if (StateMachine)
	{
		StateMachine->InputSignal(EInputSignal::Dash, Value);
	}
}
void APlayerController2D::OnJump(const FInputActionValue& Value)
{
	if (StateMachine)
	{
		StateMachine->InputSignal(EInputSignal::Jump, Value);
	}
}

void APlayerController2D::OnAttack(const FInputActionValue& Value)
{
	if (StateMachine)
	{
		StateMachine->InputSignal(EInputSignal::Attack, Value);
	}
}